package com.xcesys.extras.tool.reveng;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Properties;

import org.hibernate.cfg.reveng.DelegatingReverseEngineeringStrategy;
import org.hibernate.cfg.reveng.ReverseEngineeringStrategy;
import org.hibernate.cfg.reveng.TableIdentifier;
import org.hibernate.mapping.MetaAttribute;

public class ExtrasReverseStrategy extends DelegatingReverseEngineeringStrategy {
	private static List<String> excludFields = null;
	private String prefix = Config.getString("table.prefix"); //$NON-NLS-1$
	private String startWith = Config.getString("table.startWith"); //$NON-NLS-1$

	public ExtrasReverseStrategy(ReverseEngineeringStrategy delegate) {
		super(delegate);
		excludFields = new ArrayList<String>();
		excludFields.add("CREATE_BY"); //$NON-NLS-1$
		excludFields.add("CREATE_DATE"); //$NON-NLS-1$
		excludFields.add("UPDATE_BY"); //$NON-NLS-1$
		excludFields.add("UPDATE_DATE"); //$NON-NLS-1$
		excludFields.add("DELETED"); //$NON-NLS-1$
		excludFields.add("DELETE_BY"); //$NON-NLS-1$
		excludFields.add("DELETE_DATE"); //$NON-NLS-1$
		excludFields.add("VERSION"); //$NON-NLS-1$
	}

	// change PK property name to id;
	@Override
	public String columnToPropertyName(TableIdentifier table, String column) {
		if (isPKcolumn(column, table.getName())) {
			return "id"; //$NON-NLS-1$
		} else {
			return super.columnToPropertyName(table, column);
		}
	}

	@Override
	public boolean excludeColumn(TableIdentifier identifier, String columnName) {
		return excludFields.contains(columnName.toUpperCase());
	}

	private String getPKName(String tablename) {
		try {
			String pkname = tablename + "_id"; //$NON-NLS-1$
			if ((prefix != null && !"".equals(prefix.trim()))
					&& tablename.toLowerCase().startsWith(prefix)) {
				pkname = pkname.substring((prefix + "_").length()); //$NON-NLS-1$
			}
			return pkname.toUpperCase();
		} catch (Exception e) {
			e.printStackTrace();
			return ""; //$NON-NLS-1$
		}
	}

	public String getPrefix() {
		return prefix;
	}

	// set the ID generator
	@Override
	public Properties getTableIdentifierProperties(TableIdentifier identifier) {
		Properties props = new Properties();
		String tableName = identifier.getName();
		String pk = getPKName(tableName);
		String seqname = ("seq_" + pk); //$NON-NLS-1$
		seqname = seqname.toUpperCase();
		System.out.print(seqname);
		props.put("sequence_name", seqname); //$NON-NLS-1$
		return props;
	}

	// set sequence generator
	@Override
	public String getTableIdentifierStrategyName(TableIdentifier identifier) {
		return "org.hibernate.id.enhanced.SequenceStyleGenerator"; //$NON-NLS-1$
	}

	private boolean isPKcolumn(String column, String tablename) {
		// 检查表名+"_ID"是否等于column名字
		String pkName = getPKName(tablename);
		return column.equalsIgnoreCase(pkName);
	}

	public void setPrefix(String prefix) {
		this.prefix = prefix;
	}

	@Override
	public String tableToClassName(TableIdentifier tableIdentifier) {
		String clsname = super.tableToClassName(tableIdentifier);
		int idx = clsname.lastIndexOf('.');
		if (idx >= 0) {
			String temp = clsname.substring(idx + 1);
			if (temp.toLowerCase().startsWith(prefix)) {
				temp = temp.substring(prefix.length());
			}
			if (startWith != null && startWith.trim().length() > 0) {
				String tableName = tableIdentifier.getName();
				System.out.println("####### Table Name: " + tableName); //$NON-NLS-1$
				int idx2 = tableName.indexOf("_");
				if (idx2 > 0) {
					String pre = tableName.substring(0, idx2);
					String[] split = startWith.toLowerCase().split(",");
					if (Arrays.asList(split).contains(pre.toLowerCase())) {
						temp = temp.substring(idx2);
					}

				}
			}
			clsname = clsname.substring(0, idx + 1) + temp;
		} else {
			clsname = clsname.substring(prefix.length());
		}

		System.out.println("####### Class Name: " + clsname); //$NON-NLS-1$
		return clsname;
	}

	@Override
	@SuppressWarnings({ "rawtypes", "unchecked" })
	public Map tableToMetaAttributes(TableIdentifier table) {
		Map<String, MetaAttribute> m = new HashMap<String, MetaAttribute>();
		MetaAttribute scopefield = new MetaAttribute("scope-field"); //$NON-NLS-1$
		scopefield.addValue("protected"); //$NON-NLS-1$

		MetaAttribute extraimport = new MetaAttribute("extra-import"); //$NON-NLS-1$
		extraimport
				.addValue("com.xcesys.extras.core.dao.model.VersionableEntity"); //$NON-NLS-1$

		MetaAttribute extendsma = new MetaAttribute("extends"); //$NON-NLS-1$
		extendsma.addValue("VersionableEntity"); //$NON-NLS-1$

		m.put(scopefield.getName(), scopefield);
		m.put(extraimport.getName(), extraimport);
		m.put(extendsma.getName(), extendsma);

		Map sas = super.tableToMetaAttributes(table);
		if (sas != null) {
			m.putAll(sas);
		}

		return m;
	}

}
